home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / examples / demo / opengl / fbm.c.z / fbm.c
C/C++ Source or Header  |  2002-04-08  |  4KB  |  208 lines

  1. /*****************************************************************
  2.  
  3.   Implementation of the fractional Brownian motion algorithm. These
  4.   functions were originally the work of F. Kenton Musgrave.
  5.   For documentation of the different functions please refer to the
  6.   book: 
  7.   "Texturing and modeling: a procedural approach"
  8.   by David S. Ebert et. al.
  9.  
  10. ******************************************************************/
  11.  
  12. #if defined (_MSC_VER)
  13. #include <qglobal.h>
  14. #endif
  15.  
  16. #include <time.h>
  17. #include <stdlib.h>
  18. #include "fbm.h"
  19.  
  20. #if defined(Q_CC_MSVC)
  21. #pragma warning(disable:4244)
  22. #endif
  23.  
  24. /* Definitions used by the noise2() functions */
  25.  
  26. #define B 0x100
  27. #define BM 0xff
  28.  
  29. #define N 0x1000
  30. #define NP 12   /* 2^N */
  31. #define NM 0xfff
  32.  
  33. static int   p[B + B + 2];
  34. static float g3[B + B + 2][3];
  35. static float g2[B + B + 2][2];
  36. static float g1[B + B + 2];
  37. static int   start = 1;
  38.  
  39. static void init(void);
  40.  
  41. #define s_curve(t) ( t * t * (3. - 2. * t) )
  42.  
  43. #define lerp(t, a, b) ( a + t * (b - a) )
  44.  
  45. #define setup(i,b0,b1,r0,r1)\
  46.     t = vec[i] + N;\
  47.     b0 = ((int)t) & BM;\
  48.     b1 = (b0+1) & BM;\
  49.     r0 = t - (int)t;\
  50.     r1 = r0 - 1.;
  51. #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
  52.  
  53. /* Fractional Brownian Motion function */
  54.  
  55. double fBm( Vector point, double H, double lacunarity, double octaves,
  56.         int init )
  57. {
  58.  
  59.     double            value, frequency, remainder;
  60.     int               i;
  61.     static double     exponent_array[10];
  62.     float             vec[3];
  63.  
  64.     /* precompute and store spectral weights */
  65.     if ( init ) {
  66.     start = 1;
  67.     srand( time(0) );
  68.     /* seize required memory for exponent_array */
  69.     frequency = 1.0;
  70.     for (i=0; i<=octaves; i++) {
  71.         /* compute weight for each frequency */
  72.         exponent_array[i] = pow( frequency, -H );
  73.         frequency *= lacunarity;
  74.     }
  75.     }
  76.  
  77.     value = 0.0;            /* initialize vars to proper values */
  78.     frequency = 1.0;
  79.     vec[0]=point.x;
  80.     vec[1]=point.y;
  81.     vec[2]=point.z;
  82.  
  83.  
  84.     /* inner loop of spectral construction */
  85.     for (i=0; i<octaves; i++) {
  86.     /* value += noise3( vec ) * exponent_array[i];*/
  87.     value += noise3( vec ) * exponent_array[i];
  88.     vec[0] *= lacunarity;
  89.     vec[1] *= lacunarity;
  90.     vec[2] *= lacunarity;
  91.     } /* for */
  92.  
  93.     remainder = octaves - (int)octaves;
  94.     if ( remainder )      /* add in ``octaves''  remainder */
  95.     /* ``i''  and spatial freq. are preset in loop above */
  96.     value += remainder * noise3( vec ) * exponent_array[i];
  97.  
  98.     return( value );
  99.  
  100. } /* fBm() */
  101.  
  102.  
  103. float noise3(float vec[3])
  104. {
  105.     int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  106.     float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
  107.     register int i, j;
  108.  
  109.     if (start) {
  110.     start = 0;
  111.     init();
  112.     }
  113.  
  114.     setup(0, bx0,bx1, rx0,rx1);
  115.     setup(1, by0,by1, ry0,ry1);
  116.     setup(2, bz0,bz1, rz0,rz1);
  117.  
  118.     i = p[ bx0 ];
  119.     j = p[ bx1 ];
  120.  
  121.     b00 = p[ i + by0 ];
  122.     b10 = p[ j + by0 ];
  123.     b01 = p[ i + by1 ];
  124.     b11 = p[ j + by1 ];
  125.  
  126.     t  = s_curve(rx0);
  127.     sy = s_curve(ry0);
  128.     sz = s_curve(rz0);
  129.  
  130.  
  131.     q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
  132.     q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
  133.     a = lerp(t, u, v);
  134.  
  135.     q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
  136.     q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
  137.     b = lerp(t, u, v);
  138.  
  139.     c = lerp(sy, a, b);
  140.  
  141.     q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
  142.     q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
  143.     a = lerp(t, u, v);
  144.  
  145.     q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
  146.     q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
  147.     b = lerp(t, u, v);
  148.  
  149.     d = lerp(sy, a, b);
  150.  
  151.     return lerp(sz, c, d);
  152. }
  153.  
  154. static void normalize2(float v[2])
  155. {
  156.     float s;
  157.  
  158.     s = sqrt(v[0] * v[0] + v[1] * v[1]);
  159.     v[0] = v[0] / s;
  160.     v[1] = v[1] / s;
  161. }
  162.  
  163. static void normalize3(float v[3])
  164. {
  165.     float s;
  166.  
  167.     s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  168.     v[0] = v[0] / s;
  169.     v[1] = v[1] / s;
  170.     v[2] = v[2] / s;
  171. }
  172.  
  173. static void init(void)
  174. {
  175.     int i, j, k;
  176.     
  177.     for (i = 0 ; i < B ; i++) {
  178.     p[i] = i;
  179.  
  180.     g1[i] = (float)((rand() % (B + B)) - B) / B;
  181.  
  182.     for (j = 0 ; j < 2 ; j++)
  183.         g2[i][j] = (float)((rand() % (B + B)) - B) / B;
  184.     normalize2(g2[i]);
  185.  
  186.     for (j = 0 ; j < 3 ; j++)
  187.         g3[i][j] = (float)((rand() % (B + B)) - B) / B;
  188.     normalize3(g3[i]);
  189.     }
  190.  
  191.     while (--i) {
  192.     k = p[i];
  193.     p[i] = p[j = rand() % B];
  194.     p[j] = k;
  195.     }
  196.  
  197.     for (i = 0 ; i < B + 2 ; i++) {
  198.     p[B + i] = p[i];
  199.     g1[B + i] = g1[i];
  200.     for (j = 0 ; j < 2 ; j++)
  201.         g2[B + i][j] = g2[i][j];
  202.     for (j = 0 ; j < 3 ; j++)
  203.         g3[B + i][j] = g3[i][j];
  204.     }
  205. }
  206.  
  207.  
  208.